package Service;

import DAO.ProductsDAO;
import Entity.*;
import Service.utils.ShortestPath;

import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;

import static Config.GlobalVariables.gridList;

public class SupervisorService {
    private final List<Robot> robotList;
    private final ProductsDAO productsDAO;
    private final List<String> logs;
    private final List<String> messages;
    private int nextProductId; // 用于生成唯一产品ID
    private final List<Orders> orderQueue; // 订单队列

    public SupervisorService(List<Robot> robotList) {
        this.robotList = robotList;
        this.productsDAO = new ProductsDAO();
        this.logs = new ArrayList<>();
        this.messages = new ArrayList<>();
        this.nextProductId = getInitialProductId();
        this.orderQueue = new ArrayList<>();
    }

    // 初始化下一个产品ID
    private int getInitialProductId() {
        List<Products> products = productsDAO.getAllProducts();
        int maxId = 0;
        for (Products p : products) {
            if (p.getId() > maxId) {
                maxId = p.getId();
            }
        }
        return maxId + 1;
    }

    // 处理新订单
    public void handleNewOrder(Orders order) {
        addMessage("Received new order: " + order);

        // 不需要为订单分配唯一ID，也不需要插入新产品
        // 只需要查找对应的产品并更新库存
        Products product = productsDAO.getProductByGroupId(order.getGroupId());

        if (product != null) {
            // 更新库存：减去订单中的库存数量
            int updatedStock = product.getStock() - order.getStock();
            if (updatedStock < 0) {
                addMessage("Insufficient stock for product: " + order.getName() + ". Order cannot be fulfilled.");
            } else {
                if (updatedStock == 0) {
                    productsDAO.deleteProduct(product.getId());  // 删除库存为 0 的产品
                    addMessage("Product " + product.getName() + " removed from database due to zero stock.");
                } else {
                    product.setStock(updatedStock);
                    productsDAO.updateProduct(product);  // 更新数据库中的库存
                    addMessage("Updated stock for product: " + product.getName() + ", new stock: " + updatedStock);
                }
                // 分配给机器人
                assignToRobotForOrder(order, product);
            }
        } else {
            addMessage("Product not found for order: " + order.getName() + ". Cannot process order.");
        }
    }

    // 处理新产品
    public void handleNewProduct(Products product) {
        addMessage("Received new product: " + product);

        // 分配唯一ID（如果尚未分配）
        if (product.getId() != -1) {
            int uniqueId = getNextProductId(); // 获取下一个唯一 ID
            product.setId(uniqueId);
            addMessage("Assigned unique ID: " + uniqueId + " to product: " + product.getName());
        }
        // 分配给机器人
        int[] stall = findEmptyShelf();
        product.setX(stall[0]);
        product.setY(stall[1]);
        assignToRobotForProduct(product);

        // 插入或更新数据库
        /*Products existingProduct = productsDAO.getProductById(product.getId());
        if (existingProduct == null) {
            productsDAO.addProduct(product);  // 如果产品不存在，则插入
            addMessage("Product inserted into database: " + product);
        } else {
            // 如果产品已存在，更新库存量
            int updatedStock = existingProduct.getStock() + product.getStock(); // 合并库存
            product.setStock(updatedStock); // 更新产品的库存数量
            productsDAO.updateProduct(product);  // 更新数据库中的产品
            addMessage("Product updated in database: " + product);
        }*/
    }


    // 分配产品给可用机器人
    // 分配产品给可用机器人
    // 处理订单的分配
    private void assignToRobotForOrder(Orders order, Products product) {
        Robot availableRobot = findAvailableRobot();
        if (availableRobot != null) {
            addMessage("Assigning robot " + availableRobot.getId() + " to order: " + order.getName());

            List<int[]> path1;
            List<int[]> path2;
            List<int[]> wholepath = new ArrayList<>();
            ShortestPath shortestPath = new ShortestPath(gridList);


            int[] start = new int[]{(int) availableRobot.getX(), (int) availableRobot.getY()};

            // 获取出货口的位置
            OutboundCounter orderCounter = order.getCounter();  // 获取订单的出货口
            int[] end2 = new int[]{orderCounter.getX(), orderCounter.getY()};  // 出货口坐标

            // 从数据库查询与订单相同groupId的货品，获取其货架位置（end1）
            Products productInOrder = product;  // 获取与订单匹配的产品
            if (productInOrder == null) {
                addMessage("No product found in the database with groupId: " + order.getGroupId());
                return;
            }

            // 获取货架坐标（假设产品类有x, y字段表示货架的位置）
            int[] end1 = new int[]{productInOrder.getX() , productInOrder.getY()};  // 从产品信息获取货架坐标

            // 计算路径：机器人当前位置 -> 货架 -> 出货口
            path1 = shortestPath.findShortestPath(start, end1);  // 从机器人当前位置到货架
            path2 = shortestPath.findShortestPath(end1, end2);  // 货架点
            // 出货口点
            wholepath.addAll(path1);
            wholepath.addAll(path2);
            // 设置路径给机器人
            for (int[] path : wholepath)
                System.out.println(Arrays.toString(path));
            availableRobot.setPath(wholepath);
            availableRobot.setStatus(RobotStatus.ACTIVE);
            availableRobot.setCurrentIndex(0);
            // 设置 pickup 和 putdown 索引
            int pickupIndex = path1.size() ; // 目标是从货架取货
            int putdownIndex = wholepath.size();  // 最后一个是放货点（出货口）
            availableRobot.setPickupIndex(pickupIndex);
            availableRobot.setPutdownIndex(putdownIndex);

            addLog("Robot " + availableRobot.getId() + " is moving to pickup location.");
        } else {
            addLog("No available robot for order: " + order.getName() + ". Placing order on hold.");
            // 如果没有可用的机器人，可以将订单放入等待队列
        }
    }

    // 处理新货品的分配
    private void assignToRobotForProduct(Products product) {
        Robot availableRobot = findAvailableRobot();

        if (availableRobot != null) {
            addMessage("Assigning robot " + availableRobot.getId() + " to product: " + product.getName());
            List<int[]> path1;
            List<int[]> path2;
            List<int[]> wholepath = new ArrayList<>();

            ShortestPath shortestPath = new ShortestPath(gridList);

            // 获取产品的入货口（即起始位置）
            InboundCounter inboundCounter = product.getCounter();  // 获取入货口
            int[] start = new int[]{(int) availableRobot.getX(), (int) availableRobot.getY()};

            // 选择空闲货架的坐标（假设你有方法去获取空闲货架）
            int[] end1 = new int[]{inboundCounter.getX(), inboundCounter.getY()};
            // 入货口的坐标
            //int[] end2 =findEmptyShelf();
            int[] end2 = {product.getX(),product.getY()}; // 获取空闲货架的坐标

            // 计算路径：机器人当前位置 -> 入货口 -> 空闲货架
            path1 = shortestPath.findShortestPath(start, end1);
            path2 = shortestPath.findShortestPath(end1, end2);  // 入货口
            wholepath.addAll(path1);
            wholepath.addAll(path2);

            // 设置路径给机器人
            availableRobot.setPath(wholepath);
            availableRobot.setStatus(RobotStatus.ACTIVE);
            availableRobot.setCurrentIndex(0);
            // 设置 pickup 和 putdown 索引
            int pickupIndex = path1.size() ;
            ; // 目标是从入货口取货
            int putdownIndex = wholepath.size();  // 最后一个是放货点（空闲货架）
            availableRobot.setPickupIndex(pickupIndex);
            availableRobot.setPutdownIndex(putdownIndex);
            availableRobot.isimportorder=true;
            availableRobot.product=product;
            addLog("Robot " + availableRobot.getId() + " is moving to pickup location.");
        } else {
            addLog("No available robot for product: " + product.getName() + ". Placing product on hold.");
            // 如果没有可用的机器人，可以将产品放入等待队列
        }
    }


    public int[] findEmptyShelf() {
        List<int[]> emptyShelves = new ArrayList<>();
        // 遍历书架的每个位置
        for (int col = 2; col <= 28; col += 3) {  // 书架列数
            for (int row = 1; row <= 17; row += 6) {  // 书架行数
                for (int i = 0; i < 2; i++) {  // 书架宽度
                    for (int j = 0; j < 5; j++) {  // 书架高度
                        // 当前书架位置 (row + j, col + i)
                        int x = row + j;
                        int y = col + i;

                        // 检查该位置是否有产品
                        if (!isShelfOccupied(x, y)) {
//                            // 如果该位置为空，返回 (x, y)
//                            return new int[]{x, y};
                            // 如果该位置为空，将 (x, y) 添加到列表中
                            emptyShelves.add(new int[]{x, y});
                        }
                    }
                }
            }
        }
        // 如果没有空闲书架，返回 null
//        return null;
        // 如果没有空闲书架，返回 null
        if (emptyShelves.isEmpty()) {
            return null;
        }

        // 随机选择一个空闲书架位置
        Random random = new Random();
        return emptyShelves.get(random.nextInt(emptyShelves.size()));
    }

    // 检查位置 (x, y) 是否已被产品占用
    private boolean isShelfOccupied(int x, int y) {
        // 获取所有产品，检查是否有产品在 (x, y) 位置
        List<Products> products = productsDAO.getAllProducts();
        for (Products product : products) {
            if (product.getX() == x && product.getY() == y) {
                return true;  // 如果位置已被占用，返回 true
            }
        }
        return false;  // 如果没有产品占用，返回 false
    }

    // 查找一个可用的机器人（非活动状态）
    private Robot findAvailableRobot() {
        for (Robot robot : robotList) {
            if (robot.getStatus() == RobotStatus.INACTIVE) {
                return robot;
            }
        }
        return null;
    }

    // 生成下一个唯一产品ID
    private synchronized int getNextProductId() {
        return nextProductId++;
    }

    // 停用机器人
    public void deactivateRobot(String robotId) {
        for (Robot robot : robotList) {
            if (robot.getId().equals(robotId)) {
                if (robot.getStatus() != RobotStatus.DEACTIVATED) {
                    robot.setStatus(RobotStatus.DEACTIVATED);
                    // 指定路径移动到充电站
                    List<int[]> path = new ArrayList<>();
                    path.add(new int[]{(int) robot.getX(), (int) robot.getY()});
                    path.add(new int[]{0, 0});
                    robot.setPath(path);
                    addLog("Robot " + robotId + " deactivated and moving to charging station.");
                } else {
                    addLog("Robot " + robotId + " is already deactivated.");
                }
                break;
            }
        }
    }

    // 重新激活机器人
    public void reactivateRobot(String robotId) {
        for (Robot robot : robotList) {
            if (robot.getId().equals(robotId)) {
                if (robot.getStatus() == RobotStatus.DEACTIVATED) {
                    robot.setStatus(RobotStatus.INACTIVE);
                    addLog("Robot " + robotId + " reactivated and now inactive.");
                } else {
                    addLog("Robot " + robotId + " is not deactivated.");
                }
                break;
            }
        }
    }

    // 更新机器人状态（定时器调用）
    public void updateRobots() {
        for (Robot robot : robotList) {
            if (robot.getStatus() == RobotStatus.ACTIVE && robot.getPath() != null && !robot.getPath().isEmpty()) {
                // 机器人开始移动
                robot.move();

                // 如果机器人移动完成，则记录移动日志
                addLog("Robot " + robot.getId() + " moved to (" + robot.getX() + ", " + robot.getY() + ")");

                // 执行 pickup 或 putdown 操作
                if (robot.isCarryingProduct()) {
                    // 如果机器人正在携带产品，检查是否到达出货点
                    if (robot.getCurrentIndex() == robot.getPutdownIndex()) {
                        if(robot.isimportorder==true){
                        Products existingProduct = productsDAO.getProductById(robot.product.getId());
                        if (existingProduct == null) {
                            productsDAO.addProduct(robot.product);  // 如果产品不存在，则插入
                            addMessage("Product inserted into database: " + robot.product);
                        } else {
                            // 如果产品已存在，更新库存量
                            int updatedStock = existingProduct.getStock() + robot.product.getStock(); // 合并库存
                            robot.product.setStock(updatedStock); // 更新产品的库存数量
                            productsDAO.updateProduct(robot.product);  // 更新数据库中的产品
                            addMessage("Product updated in database: " + robot.product);
                        }
                            robot.isimportorder=false;
                        }
                        robot.putdown();  // 执行 putdown
                        // 获取当前坐标
                        int currentX = (int) robot.getX();
                        int currentY = (int) robot.getY();
                        // 更新 gridList
                        if (gridList.get(currentX).get(currentY) == 1) {
                            gridList.get(currentX).set(currentY, 2);
                        }

                        addLog("Robot " + robot.getId() + " put down the product at (" + robot.getX() + ", " + robot.getY() + ")");
                    }
                } else {
                    // 如果机器人没有携带产品，执行 pickup 操作（检查是否到达取货点）
                    if (robot.getCurrentIndex() == robot.getPickupIndex()) {
                        robot.pickup();  // 执行 pickup
                        // 获取当前坐标
                        int currentX = (int) robot.getX();
                        int currentY = (int) robot.getY();
                        // 更新 gridList
                        if (gridList.get(currentX).get(currentY) == 2) {
                            gridList.get(currentX).set(currentY, 1);
                        }

                        addLog("Robot " + robot.getId() + " picked up the product at (" + robot.getX() + ", " + robot.getY() + ")");
                    }
                }

            }
            if (robot.getStatus() == RobotStatus.INACTIVE &&robot.getBattery()<70){
                robot.setStatus(RobotStatus.CHARGING);
                ShortestPath shortestPath = new ShortestPath(gridList);

                // 获取产品的入货口（即起始位置）
                ChargingStations station = robot.chargingStations;  // 获取入货口
                int[] start = new int[]{(int) robot.getX(), (int) robot.getY()};

                // 选择空闲货架的坐标（假设你有方法去获取空闲货架）
                int[] end1 = new int[]{station.getX(), station.getY()};
                // 入货口的坐标
                //int[] end2 =findEmptyShelf();
                List<int[]> path1;
                // 计算路径：机器人当前位置 -> 入货口 -> 空闲货架
                path1 = shortestPath.findShortestPath(start, end1);
                robot.setPath(path1);
                robot.setCurrentIndex(0);
                robot.setPutdownIndex(-100);
                robot.setPickupIndex(-100);

            }
            if (robot.getStatus() == RobotStatus.CHARGING ){
                ChargingStations station = robot.chargingStations;
                robot.move();
                if(robot.getX()== station.getX()&&robot.getY()==station.getY())
                    robot.setBattery(robot.getBattery()+10);
                if(robot.getBattery()>280)robot.setStatus(RobotStatus.INACTIVE);
            }
        }
    }


    // 获取所有机器人状态
    public List<Robot> getAllRobots() {
        return robotList;
    }

    // 获取日志
    public List<String> getLogs() {
        return logs;
    }

    // 获取消息
    public List<String> getMessages() {
        return messages;
    }

    // 添加日志
    private void addLog(String logEntry) {
        logs.add(logEntry);
    }

    // 添加消息
    private void addMessage(String message) {
        messages.add(message);
    }
}
